import React, { useState, useRef } from 'react';
import { DndProvider, useDrag, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';

// 命令类型定义
const COMMAND_TYPES = {
    INTERACTIVE: ['click', 'hover', 'select', 'dbclick'],
    CONTROL: ['while', 'times', 'if', 'elseif', 'else']
};

// 命令数据结构
const initialCommands = [
    // 交互命令
    { id: 'cmd-click', cmd: 'click', description: '点击元素' },
    { id: 'cmd-hover', cmd: 'hover', description: '悬停在元素上' },
    { id: 'cmd-select', cmd: 'select', description: '从下拉列表选择' },
    { id: 'cmd-dbclick', cmd: 'dbclick', description: '双击元素' },

    // 控制命令
    { id: 'cmd-while', cmd: 'while', description: '条件为真时循环' },
    { id: 'cmd-times', cmd: 'times', description: '执行指定次数的循环' },
    { id: 'cmd-if', cmd: 'if', description: '条件判断' },
    { id: 'cmd-elseif', cmd: 'elseif', description: '其他条件分支' },
    { id: 'cmd-else', cmd: 'else', description: '默认分支' }
];

// 任务数据结构
const initialTasks = [
    {
        id: 'task-1',
        cmd: 'if',
        target: 'price > 100',
        value: '',
        description: '检查价格是否高于100',
        children: [
            {
                id: 'task-2',
                cmd: 'click',
                target: '#discountBtn',
                value: '',
                description: '点击折扣按钮',
                children: []
            }
        ]
    },
    {
        id: 'task-3',
        cmd: 'times',
        target: '5',
        value: '',
        description: '执行5次',
        children: [
            {
                id: 'task-4',
                cmd: 'hover',
                target: '#product',
                value: '',
                description: '悬停在产品上',
                children: []
            },
            {
                id: 'task-5',
                cmd: 'select',
                target: '#colorSelect',
                value: 'red',
                description: '选择红色',
                children: []
            }
        ]
    }
];

// 拖拽项组件
const DraggableItem = ({ id, type, onDrop, children }) => {
    const [{ isDragging }, drag] = useDrag(() => ({
        type,
        item: { id, type },
        collect: (monitor) => ({
            isDragging: monitor.isDragging(),
        }),
    }));

    return (
        <div
            ref={drag}
            style={{ opacity: isDragging ? 0.5 : 1 }}
            className="draggable-item"
        >
            {children}
        </div>
    );
};

// 可放置区域组件
const DroppableArea = ({ onDrop, depth = 0, isControlCommand = false, children }) => {
    const ref = useRef(null);
    const [{ handlerId, isOver, canDrop }, drop] = useDrop({
        accept: ['command', 'task'],
        collect: (monitor) => ({
            handlerId: monitor.getHandlerId(),
            isOver: monitor.isOver({ shallow: true }),
            canDrop: monitor.canDrop(),
        }),
        drop: (item, monitor) => {
            const didDrop = monitor.didDrop();
            if (didDrop) return;

            if (ref.current) {
                const dropPosition = determineDropPosition(ref.current, monitor.getClientOffset());
                onDrop(item, dropPosition);
                return undefined;
            }
        }
    });

    drop(ref);

    // 根据拖拽位置确定插入位置（before, after, inside）
    const determineDropPosition = (node, clientOffset) => {
        if (!node || !clientOffset) return null;

        const rect = node.getBoundingClientRect();
        const offsetY = clientOffset.y - rect.top;
        const height = rect.bottom - rect.top;

        // 顶部25%区域为上方插入
        if (offsetY < height * 0.25) return 'before';
        // 中间30%区域为内部插入（控制命令才允许）
        if (offsetY > height * 0.35 && offsetY < height * 0.65 && isControlCommand) return 'inside';
        // 底部25%区域为下方插入
        if (offsetY > height * 0.75) return 'after';

        return 'after';
    };

    // 根据拖拽位置渲染不同的指示器
    const renderDropIndicator = () => {
        if (!isOver || !canDrop) return null;

        return (
            <div className="drop-indicator-container">
                {['before', 'after'].map(position => (
                    <div
                        key={position}
                        className={`drop-indicator-line drop-indicator-${position} ${isOver ? 'active' : ''}`}
                    />
                ))}
                {isControlCommand && (
                    <div
                        className={`drop-indicator-area ${isOver ? 'active' : ''}`}
                    />
                )}
            </div>
        );
    };

    return (
        <div
            ref={ref}
            className="droppable-area"
            style={{
                position: 'relative',
                borderLeft: depth > 0 ? `2px solid #e0e0e0` : 'none',
                paddingLeft: depth > 0 ? '15px' : '0'
            }}
            data-handler-id={handlerId}
        >
            {renderDropIndicator()}
            {children}
        </div>
    );
};

// 命令列表项组件
const CommandItem = ({ command, onAdd }) => {
    return (
        <DraggableItem id={command.id} type="command">
            <div className="command-card">
                <div className="command-header">
                    <span className={`command-type ${COMMAND_TYPES.CONTROL.includes(command.cmd) ? 'control' : 'interactive'}`}>
                        {command.cmd}
                    </span>
                </div>
                <div className="command-content">
                    <div className="command-description">{command.description}</div>
                </div>
            </div>
        </DraggableItem>
    );
};

// 任务节点组件
const TaskNode = ({ task, depth, onDelete, onUpdate, onDrop }) => {
    const [isEditing, setIsEditing] = useState(false);
    const [editableTask, setEditableTask] = useState({ ...task });

    const isControlCommand = COMMAND_TYPES.CONTROL.includes(task.cmd);
    const hasChildren = isControlCommand && task.children && task.children.length > 0;

    const handleSave = () => {
        onUpdate(editableTask);
        setIsEditing(false);
    };

    const handleChange = (field, value) => {
        setEditableTask({ ...editableTask, [field]: value });
    };

    const renderEditor = () => (
        <div className="task-editor">
            <div className="form-group">
                <label>Target</label>
                <input
                    type="text"
                    value={editableTask.target || ''}
                    onChange={(e) => handleChange('target', e.target.value)}
                />
            </div>
            <div className="form-group">
                <label>Value</label>
                <input
                    type="text"
                    value={editableTask.value || ''}
                    onChange={(e) => handleChange('value', e.target.value)}
                />
            </div>
            <div className="form-group">
                <label>Description</label>
                <input
                    type="text"
                    value={editableTask.description || ''}
                    onChange={(e) => handleChange('description', e.target.value)}
                />
            </div>
            <div className="editor-actions">
                <button className="save-btn" onClick={handleSave}>Save</button>
                <button className="cancel-btn" onClick={() => setIsEditing(false)}>Cancel</button>
            </div>
        </div>
    );

    const renderView = () => (
        <>
            <div className="task-info">
                <span className={`command-type ${isControlCommand ? 'control' : 'interactive'}`}>
                    {task.cmd}
                </span>
                {task.target && <div className="task-target">{task.target}</div>}
                {task.value && <div className="task-value">Value: {task.value}</div>}
                <div className="task-description">{task.description}</div>
            </div>
            <div className="task-actions">
                <button className="edit-btn" onClick={() => setIsEditing(true)}>Edit</button>
                <button className="delete-btn" onClick={() => onDelete(task.id)}>Delete</button>
            </div>
        </>
    );

    return (
        <DroppableArea
            onDrop={(item, position) => onDrop(item, position, task.id)}
            depth={depth}
            isControlCommand={isControlCommand}
        >
            <DraggableItem id={task.id} type="task">
                <div className={`task-card ${isControlCommand ? 'control' : ''}`}>
                    <div className="task-header">
                        {isEditing ? renderEditor() : renderView()}
                    </div>
                </div>
            </DraggableItem>

            {hasChildren && (
                <div className="task-children">
                    {task.children.map((child) => (
                        <TaskNode
                            key={child.id}
                            task={child}
                            depth={depth + 1}
                            onDelete={onDelete}
                            onUpdate={onUpdate}
                            onDrop={onDrop}
                        />
                    ))}
                </div>
            )}
        </DroppableArea>
    );
};

// 命令列表组件
const CommandList = ({ commands, onAddCommand }) => {
    // 将命令分类为交互命令和控制命令
    const interactiveCommands = commands.filter(cmd =>
        COMMAND_TYPES.INTERACTIVE.includes(cmd.cmd)
    );

    const controlCommands = commands.filter(cmd =>
        COMMAND_TYPES.CONTROL.includes(cmd.cmd)
    );

    return (
        <div className="command-list">
            <h3>交互命令</h3>
            <div className="command-category">
                {interactiveCommands.map(command => (
                    <CommandItem key={command.id} command={command} />
                ))}
            </div>

            <h3>控制命令</h3>
            <div className="command-category">
                {controlCommands.map(command => (
                    <CommandItem key={command.id} command={command} />
                ))}
            </div>
        </div>
    );
};

// 任务树组件
const TaskTree = ({ tasks, onUpdateTask, onDeleteTask, onDropTask }) => {
    return (
        <div className="task-tree">
            {tasks.map((task) => (
                <TaskNode
                    key={task.id}
                    task={task}
                    depth={0}
                    onUpdate={(updatedTask) => onUpdateTask(updatedTask)}
                    onDelete={onDeleteTask}
                    onDrop={onDropTask}
                />
            ))}
        </div>
    );
};

// 主应用组件
const TaskEditorApp = () => {
    const [commands] = useState(initialCommands);
    const [tasks, setTasks] = useState(initialTasks);

    // 更新任务
    const handleUpdateTask = (updatedTask) => {
        const updateTaskInTree = (taskList) => {
            return taskList.map(task => {
                if (task.id === updatedTask.id) {
                    return updatedTask;
                }

                if (task.children && task.children.length > 0) {
                    return {
                        ...task,
                        children: updateTaskInTree(task.children)
                    };
                }

                return task;
            });
        };

        setTasks(updateTaskInTree(tasks));
    };

    // 删除任务
    const handleDeleteTask = (taskId) => {
        const deleteTaskFromTree = (taskList) => {
            return taskList.reduce((acc, task) => {
                if (task.id === taskId) {
                    return acc; // 跳过当前任务
                }

                const newTask = { ...task };

                if (newTask.children && newTask.children.length > 0) {
                    newTask.children = deleteTaskFromTree(newTask.children);
                }

                return [...acc, newTask];
            }, []);
        };

        setTasks(deleteTaskFromTree(tasks));
    };

    // 处理拖放操作
    const handleDrop = (item, position, targetId) => {
        const { id: sourceId, type: sourceType } = item;

        // 从左侧命令列表添加新命令
        if (sourceType === 'command') {
            const sourceCommand = commands.find(cmd => cmd.id === sourceId);

            if (!sourceCommand) return;

            const newTask = {
                ...sourceCommand,
                id: `task-${Date.now()}`,
                target: '',
                value: '',
                children: []
            };

            const addNewTaskToTree = (taskList, parentId, pos, newItem) => {
                return taskList.reduce((acc, task) => {
                    // 在指定位置前添加
                    if (task.id === parentId && pos === 'before') {
                        return [...acc, newItem, task];
                    }

                    // 在指定位置后添加
                    if (task.id === parentId && pos === 'after') {
                        return [...acc, task, newItem];
                    }

                    // 添加到控制命令内部
                    if (task.id === parentId && pos === 'inside' &&
                        COMMAND_TYPES.CONTROL.includes(task.cmd)) {
                        return [
                            ...acc,
                            {
                                ...task,
                                children: [...task.children, newItem]
                            }
                        ];
                    }

                    // 递归处理子节点
                    if (task.children && task.children.length > 0) {
                        return [
                            ...acc,
                            {
                                ...task,
                                children: addNewTaskToTree(task.children, parentId, pos, newItem)
                            }
                        ];
                    }

                    return [...acc, task];
                }, []);
            };

            setTasks(addNewTaskToTree(tasks, targetId, position, newTask));
            return;
        }

        // 任务树内部节点移动
        if (sourceType === 'task') {
            // 深拷贝任务树
            const deepClone = (taskList) => {
                return taskList.map(task => ({
                    ...task,
                    children: task.children ? deepClone(task.children) : []
                }));
            };

            const newTasks = deepClone(tasks);

            // 查找源任务
            let sourceTask = null;
            const removeSource = (taskList) => {
                return taskList.reduce((acc, task) => {
                    if (task.id === sourceId) {
                        sourceTask = task;
                        return acc;
                    }

                    const newTask = { ...task };
                    if (newTask.children && newTask.children.length > 0) {
                        newTask.children = removeSource(newTask.children);
                    }

                    return [...acc, newTask];
                }, []);
            };

            // 从树中移除源任务
            const cleanTasks = removeSource(newTasks);

            // 将源任务插入到指定位置
            const insertSource = (taskList, targetId, position, item) => {
                return taskList.reduce((acc, task) => {
                    // 在目标位置前插入
                    if (task.id === targetId && position === 'before') {
                        return [...acc, item, task];
                    }

                    // 在目标位置后插入
                    if (task.id === targetId && position === 'after') {
                        return [...acc, task, item];
                    }

                    // 插入到控制命令内部
                    if (task.id === targetId && position === 'inside' &&
                        COMMAND_TYPES.CONTROL.includes(task.cmd)) {
                        return [
                            ...acc,
                            {
                                ...task,
                                children: [...task.children, item]
                            }
                        ];
                    }

                    // 递归处理子节点
                    if (task.children && task.children.length > 0) {
                        return [
                            ...acc,
                            {
                                ...task,
                                children: insertSource(task.children, targetId, position, item)
                            }
                        ];
                    }

                    return [...acc, task];
                }, []);
            };

            setTasks(insertSource(cleanTasks, targetId, position, sourceTask));
        }
    };

    return (
        <DndProvider backend={HTML5Backend}>
            <div className="task-editor-app">
                <div className="command-panel">
                    <div className="panel-header">
                        <h2>Command List</h2>
                        <p>Drag commands to the task area</p>
                    </div>
                    <CommandList commands={commands} />
                </div>

                <div className="task-panel">
                    <div className="panel-header">
                        <h2>Task View</h2>
                        <p>Drag commands to build your automation flow</p>
                    </div>
                    <TaskTree
                        tasks={tasks}
                        onUpdateTask={handleUpdateTask}
                        onDeleteTask={handleDeleteTask}
                        onDropTask={handleDrop}
                    />
                </div>
            </div>
        </DndProvider>
    );
};

// 根组件
export default function App() {
    return (
        <div className="app">
            <header className="app-header">
                <h1>Automation Task Editor</h1>
                <p>Advanced React-based task editor for automation workflows</p>
            </header>
            <TaskEditorApp />
            <footer className="app-footer">
                <p>© 2023 Automation Task Editor - React Implementation</p>
            </footer>
        </div>
    );
}